import dash
from dash import html, dcc
import feffery_antd_components as fac
from dash.dependencies import Input, Output, State

from tasks import task_demo, celery_app

from time import strftime
from time import gmtime

app = dash.Dash(__name__, suppress_callback_exceptions=True, update_title=None)

app.layout = html.Div(
    [
        # 注入当前任务记录器
        dcc.Store(id='current-task-record'),

        fac.AntdSpace(
            [
                fac.AntdButton(
                    '执行新任务',
                    id='button-demo',
                    type='primary'
                ),
                # 当任务被创建后，会动态生成轮询器开始辅助任务状态更新
                dcc.Interval(
                    id='current-task-interval',
                    n_intervals=0,
                    interval=250
                )
            ]
        ),

        # 执行结果容器
        html.Div(id='task-result')
    ],
    style={
        'padding': '50px'
    }
)


@app.callback(
    [Output('button-demo', 'disabled'),
     Output('current-task-record', 'data')],
    [Input('button-demo', 'nClicks'),
     Input('current-task-interval', 'n_intervals')],
    State('current-task-record', 'data'),
    prevent_initial_call=True
)
def start_new_task(nClicks, n_intervals, current_task_record):

    trigger_id = dash.ctx.triggered_id

    if trigger_id == 'button-demo':
        # 创建新任务
        new_task = task_demo.delay(1, 2)

        return [
            # 禁用按钮
            True,
            # 更新当前任务记录
            {
                'task_id': new_task.id,
                'status': '执行中',
                'n_intervals': n_intervals
            }
        ]

    else:
        if current_task_record and current_task_record.get('status') == '执行中':
            # 查询当前任务执行信息
            current_task = task_demo.AsyncResult(
                current_task_record.get('task_id')
            )

            if current_task.ready():
                return [
                    False,
                    {
                        'task_id': current_task.id,
                        'status': '已完成'
                    }
                ]

            return [
                True,
                dash.no_update
            ]

    return [
        False,
        dash.no_update
    ]


@app.callback(
    Output('task-result', 'children'),
    Input('current-task-interval', 'n_intervals'),
    State('current-task-record', 'data'),
)
def render_task_result(n_intervals, current_task_record):

    if current_task_record:
        if current_task_record.get('status') == '执行中':
            sec = n_intervals - current_task_record.get('n_intervals')
            return fac.AntdAlert(
                type='info',
                message='执行中... {}'.format(strftime("%M:%S", gmtime(sec/4)))
            )

        # 查询当前任务执行信息
        current_task = task_demo.AsyncResult(
            current_task_record.get('task_id')
        )

        return fac.AntdAlert(
            type='info',
            message='执行完成！ 任务计算结果：{}'.format(current_task.get())
        )


if __name__ == '__main__':
    app.run_server(debug=True)
